package com.kcs.fxmargin.service;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.kcs.common.utils.ConnectionUtils;
import com.kcs.common.utils.Constant;
import com.kcs.common.utils.OIDGenerator;
import com.kcs.common.utils.commonUtils;
import com.kcs.dc.service.bean.request.xsd.WsInquiryReqBody;
import com.kcs.dc.service.bean.request.xsd.WsInquiryReqHeader;
import com.kcs.dc.service.bean.request.xsd.WsInquiryRequest;
import com.kcs.dc.service.bean.response.xsd.WsInquiryResBody;
import com.kcs.dc.service.bean.response.xsd.WsInquiryResponse;
import com.kcs.dc.service.impl.WsInquirePortTypeProxy;
import com.kcs.fxmargin.bo.OutstandingBO;
import com.kcs.fxmargin.bo.PreSettlementBO;
import com.kcs.fxmargin.bo.ValidateSettlementBO;
import com.kcs.fxmargin.dao.DealsDao;
import com.kcs.fxmargin.model.TDeals;
import com.kcs.fxmargin.model.TDealsSettle;

public class DealsService {

	private Logger logDealCenter = Logger.getLogger(Constant.LOG_DEAL_CENTER);
	private static final String serviceId  	= "WS0001";
	private static final String system		= "EE";
	private static DealsDao dao = new DealsDao();
	
	public List<ValidateSettlementBO> search(TDeals deals) throws Exception {
		
		Connection conn 				= null;
		PreparedStatement pstm 			= null;
		ResultSet rs					= null;
		List<ValidateSettlementBO> validateSettlementBOList = new ArrayList<ValidateSettlementBO>();
		
		try{
			conn = ConnectionUtils.getConnection(Constant.MSSQL, Constant.TO); // get connection fxmargin from mssql
			validateSettlementBOList = dao.search(conn, pstm, rs, deals);
			
		} catch (Exception e){
			throw e;
		} finally {
			if(conn != null ) conn.close();
			if(pstm != null ) pstm.close();
			if(rs   != null ) rs.close();
		}
		
		return validateSettlementBOList;
	}
	
	public List<PreSettlementBO> searchPreSettlement() throws Exception {
		Connection conn 				= null;
		PreparedStatement pstm 			= null;
		ResultSet rs					= null;
		List<PreSettlementBO> preSettleBoList = new ArrayList<PreSettlementBO>();
		
		try{
			conn = ConnectionUtils.getConnection(Constant.MSSQL, Constant.TO); // get connection fxmargin from mssql
			preSettleBoList = dao.searchPreSettlement(conn, pstm, rs);
			
		} catch (Exception e){
			throw e;
		} finally {
			if(conn != null ) conn.close();
			if(pstm != null ) pstm.close();
			if(rs   != null ) rs.close();
		}
		
		return preSettleBoList;
	}
	
	public String update(List<TDealsSettle> modelList) throws Exception {
		
		Connection conn 				= null;
		PreparedStatement pstm 			= null;
		String result					= "s";
		try{
			conn = ConnectionUtils.getConnection(Constant.MSSQL, Constant.TO); // get connection fxmargin from mssql
			
			stop:
			for(TDealsSettle deals: modelList){
				if("s".equals(result)){
					
					if(deals.getId() != null && !"".equals(deals.getId())){
						result = dao.update(conn, pstm, deals);
					} else {
						deals.setId(OIDGenerator.create());
						result = dao.insert(conn, pstm, deals);
					}
					
				} else {
					break stop;
				}
			}
			
			conn.commit();
		} catch (Exception e){
			result = "e";
			conn.rollback();
			throw e;
		} finally {
			if(conn != null ) conn.close();
			if(pstm != null ) pstm.close();
		}
		return result;
	}
	
	public void dealCenter()throws Exception{
		Connection conn = null;
		
		try{
			conn = ConnectionUtils.getConnection(Constant.MSSQL, Constant.TO); // get connection fxmargin from mssql
			dealCenterWithConnection(conn);
			
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}finally{
			if(conn != null ) conn.close();
		}
	}
	
	public List<OutstandingBO> searchOutstanding(OutstandingBO bo) throws Exception {
		Connection conn 				= null;
		PreparedStatement pstm 			= null;
		ResultSet rs					= null;
		List<OutstandingBO> outStandingBOList = new ArrayList<OutstandingBO>();
		
		try{
			conn = ConnectionUtils.getConnection(Constant.MSSQL, Constant.TO); // get connection fxmargin from mssql
			outStandingBOList = dao.searchOutstanding(conn, pstm, rs, bo);
			
		} catch (Exception e){
			throw e;
		} finally {
			if(conn != null ) conn.close();
			if(pstm != null ) pstm.close();
			if(rs   != null ) rs.close();
		}
		
		return outStandingBOList;
	}
	
	public void dealCenterWithConnection(Connection conn) throws Exception {
		
		logDealCenter.debug("dealCenterWithConnection : Start");
		
		PreparedStatement pstm 			= null;
		ResultSet rs					= null;
		WsInquiryReqBody body 			= null;
		WsInquiryResBody[] bodys		= null;
		WsInquiryReqHeader header 		= null;
		WsInquirePortTypeProxy proxy 	= null;
		WsInquiryRequest request 		= null;
		WsInquiryResponse response		= null;
		TDealsSettle dealsSettle		= null;
		
		Double settleAmt				= 0d;
		Double settleRemain 			= 0d;
		
		try {
			
			List<TDeals> dealsList = dao.getDeals(conn, pstm, rs);
			
			for(TDeals deals : dealsList ){
				body 		= new WsInquiryReqBody();
				header 		= new WsInquiryReqHeader();
				
				body.setBuySell(deals.getBuySell());
				body.setCcy1(deals.getCcy1());
				body.setDealId(deals.getDealId());
				
				header.setRequestID(commonUtils.formatDate(new Date(), "DDMMyyHHMMSSS"));
				header.setServiceID(serviceId);
				header.setSystem(system);
				
				request 	= new WsInquiryRequest(body, header);
				proxy		= new WsInquirePortTypeProxy();
				response 	= proxy.wsInquire(request);
				
//				logDealCenter.info(response.getHeader().getRequestID()+","+response.getHeader().getRespCode()+","+response.getHeader().getRespDesc());
				logDealCenter.info("length = " + response.getHeader().getNumberOfRec());
				
				if(response.getHeader().getNumberOfRec() == 0){ 
					// if no response data then update deals
					
					deals.setUpdateBy("SYSTEM");
					deals.setDealStatus("Complete");
					
					dao.updateDeals(conn, pstm, deals);
				} else {
					
					// if have response then check this have manual create deals settle 
					
					dealsSettle = dao.getDealsSettle(conn, pstm, rs, deals.getDealId());
					bodys = response.getBody();
					
					if(bodys != null && bodys.length > 0){
						settleAmt 		= bodys[0].getDealAmt1() - bodys[0].getOutsdAmt();
						settleRemain 	= bodys[0].getOutsdAmt();
					}
					
					if(dealsSettle == null) {
						dealsSettle = new TDealsSettle();
						
						dealsSettle.setId(OIDGenerator.create());
						dealsSettle.setDealId(deals.getDealId());
						dealsSettle.setSettleAmount(new BigDecimal(settleAmt));
						dealsSettle.setSettleRemain(new BigDecimal(settleRemain));
						dealsSettle.setActiveStatus("A");
						dealsSettle.setCreateby("SYSTEM");
						dealsSettle.setUpdateBy("SYSTEM");
						dealsSettle.setRowVersion(1);
						
						dao.insertDealsSettle(conn, pstm, dealsSettle);
					} else {
						
						dealsSettle.setSettleAmount(new BigDecimal(settleAmt));
						dealsSettle.setSettleRemain(new BigDecimal(settleRemain));
						dealsSettle.setUpdateBy("SYSTEM");
						dealsSettle.setRowVersion(dealsSettle.getRowVersion() + 1);
						
						dao.updateDealsSettle(conn, pstm, dealsSettle);
					}
				}
			}
			
		} catch (Exception e) {
			throw e;
		} finally {
			if(pstm != null ) pstm.close();
			if(rs   != null ) rs.close();
		}

		logDealCenter.debug("dealCenterWithConnection : End");
	}
}
